package com.jshop.admin.shiro;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class ShiroConfiguration {
    private static final Logger log = LoggerFactory.getLogger(ShiroConfiguration.class);

    /**
     * 注入Realm
     *
     * @return MyRealm
     */
    @Bean(name = "myRealm")
    public AuthRealm myAuthRealm() {
        AuthRealm myRealm = new AuthRealm();
        myRealm.setCacheManager(new MemoryConstrainedCacheManager());
        log.info("myRealm注册完成");
        return myRealm;
    }

    //
//    @Bean(name = "shiroDialect")
//    public ShiroDialect shiroDialect(){
//
//        return new ShiroDialect();
//
//    }
    @Bean("sessionManager")
    public SessionManager sessionManager() {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setSessionValidationSchedulerEnabled(true);
        sessionManager.setSessionIdCookieEnabled(true);
        return sessionManager;
    }

    // 创建 SecurityManager 对象
    //加上注解 @Qualifier 不然service会注入失败
    @Bean
    public DefaultWebSecurityManager securityManager(@Qualifier("myRealm") AuthRealm myShiroRealm) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(myShiroRealm);
        return securityManager;

    }

    // Filter工厂，设置对应的过滤条件和跳转条件
    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //oauth过滤
        Map<String, String> map = new LinkedHashMap<>();
        // 登出
        map.put("/logout", "logout");
        // 对所有用户认证
        map.put("/checkcenter/**", "anon");
        map.put("/websocket/**", "anon");

        map.put("/api/**", "anon");
        map.put("/doc.html", "anon");
        map.put("/login", "anon");
        map.put("/captcha.jpg", "anon");
        // 对登录跳转接口进行释放
        map.put("/sys/login", "anon");
        map.put("/err", "anon");
        map.put("/static/**", "anon");
        map.put("/js/*", "anon");
        map.put("/css/*", "anon");
        map.put("/img/*", "anon");
        map.put("/libs/*", "anon");
        map.put("/fonts/**", "anon");
        map.put("/plugins/*", "anon");
        map.put("/audio/*", "anon");
        map.put("/swagger-resources", "anon");
        map.put("/v2/api-docs", "anon");
        map.put("/v2/api-docs-ext", "anon");
        map.put("/webjars/**", "anon");
        //连接池
        map.put("/druid/**", "anon");

        map.put("/webSocket/**", "anon");
//
//         map.put("*.js","anon");
//        map.put("*.jpg","anon");
//        map.put("*.png","anon");
//        map.put("*.gif","anon");
//        map.put("*.ico","anon");
//        map.put("*.css","anon");
        //authc
        map.put("/**", "authc");
//        // 登录
//        // 注意：这里配置的 /login 是指到 @RequesutMapping(value="/login")中的 /login
        shiroFilterFactoryBean.setLoginUrl("/login");
//        // 首页
        shiroFilterFactoryBean.setSuccessUrl("/index");
//        // 错误页面，认证不通过跳转
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");
        shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
        return shiroFilterFactoryBean;
    }

    // 加入注解的使用，不加这个，注解不生效
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    // 跟上面的注解配置搭配使用，有时候加了上面的配置后注解不生效，需要加入下面的配置
    @Bean
    @ConditionalOnMissingBean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator app = new DefaultAdvisorAutoProxyCreator();
        app.setProxyTargetClass(true);
        return app;
    }


}
